package com.example.wac.constant;

import com.baidu.disconf.client.addons.properties.ReloadablePropertiesFactoryBean;
import com.baidu.disconf.client.common.update.IDisconfUpdate;import com.example.wac.job.config.ElasticJobConfigurationProperties;
import com.example.wac.job.config.ElasticJobProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.Map;
import java.util.Properties;

/**
 * @author wuancheng
 * @description
 * @date 2022-05-31 16:52:00
 */

@Slf4j
@Configuration
public class JobConfig implements IDisconfUpdate {
    @Autowired
    ReloadablePropertiesFactoryBean propertiesFactoryBean;

    @Autowired
    ElasticJobProperties elasticJobProperties;

    /**
     * 如果想在构造方法对象生成时候完成某些初始化操作，而偏偏这些初始化操作又依赖于依赖注入的对象，就无法在构造函数中实现（构造方法中注入的bean为null）
     * 此时需要@PostConstruct注解来完成，@PostConstruct 注解的方法将会在依赖注入完成后被自动调用 修饰一个非静态的void
     * 类初始化调用顺序：构造方法Constructor -> @Autowired -> @PostConstruct
     * @return
     * @throws IOException
     */
    @PostConstruct
    public Map<String, ElasticJobConfigurationProperties> JobConfig() throws IOException {
        Properties jobProperties = propertiesFactoryBean.getObject();
        return this.setJobParameters(jobProperties, elasticJobProperties);
    }

    //    private final ElasticJobProperties elasticJobProperties;
//
//    /**
//     * 如果想在构造方法对象生成时候完成某些初始化操作，而偏偏这些初始化操作又依赖于依赖注入的对象，就无法在构造函数中实现（构造方法中注入的bean为null）
//     * 此时需要@PostConstruct注解来完成，@PostConstruct 注解的方法将会在依赖注入完成后被自动调用 修饰一个非静态的void
//     * 类初始化调用顺序：构造方法Constructor -> @Autowired -> @PostConstruct
//     * @return
//     * @throws IOException
//     */
//    @PostConstruct
//    public Map<String, ElasticJobConfigurationProperties> JobConfig() throws IOException {
//        Properties jobProperties = propertiesFactoryBean.getObject();
//        return this.setJobParameters(jobProperties, elasticJobProperties);
//    }
//
//    //    private final ElasticJobProperties elasticJobProperties;
////
////    /**
////     * 构造方法注入elasticJobProperties
////     * 构造方法在postConstruct执行之前 此时需要获取下载的disconf文件
////     *
////     * @throws IOException
////     */
////    public JobConfig(ElasticJobProperties elasticJobProperties) {
////        this.elasticJobProperties = elasticJobProperties;
////        Properties jobProperties = this.getJobProperties();
////        this.setJobParameters(jobProperties, elasticJobProperties);
////    }
//
////    /**
////     * 获取stockJob.properties配置
////     *
////     * @return stockJob.properties配置
////     */
////    private Properties getJobProperties() {
////        Properties properties = new Properties();
////        InputStream inputStream = null;
////        String path = ClassLoaderUtil.getClassPath() + "/" + "stockJob.properties";
////        try {
////            inputStream = new FileInputStream(path);
////            properties.load(inputStream);
////        } catch (IOException e) {
////            log.error("读取job.properties文件失败，IO异常。", e);
////        } finally {
////            if (Objects.nonNull(inputStream)) {
////                try {
////                    inputStream.close();
////                } catch (IOException e) {
////                    log.error("输入流关闭失败", e);
////                }
////            }
////        }
////        return properties;
////    }
//
//    /**
//     * 将job.properties动态参数写入elasticJobProperties实体
//     *
//     * @param jobProperties        job.properties配置
//     * @param elasticJobProperties ElasticJob参数配置
//     */
//    private Map<String, ElasticJobConfigurationProperties> setJobParameters(Properties jobProperties, ElasticJobProperties elasticJobProperties) {
//        Map<String, ElasticJobConfigurationProperties> jobs = elasticJobProperties.getJobs();
//        // 遍历刷新job动态参数配置
//        for (Map.Entry<String, ElasticJobConfigurationProperties> entry : jobs.entrySet()) {
//            ElasticJobConfigurationProperties properties = entry.getValue();
//            properties.setCron((String) jobProperties.get(entry.getKey() + ".cron"));
//            properties.setShardingTotalCount(Integer.parseInt((String) jobProperties.get(entry.getKey() + ".shardingTotalCount")));
//            properties.setShardingItemParameters((String) jobProperties.get(entry.getKey() + ".shardingItemParameters"));
//        }
//        return jobs;
//    }
//
//    @Override
//    public void reload() throws IOException {
//        log.info("============job配置发生变化=============");
//        Properties jobProperties = propertiesFactoryBean.getObject();
//        this.setJobParameters(jobProperties, elasticJobProperties);
//    }
//}

    /**
     * 将job.properties动态参数写入elasticJobProperties实体
     *
     * @param jobProperties        job.properties配置
     * @param elasticJobProperties ElasticJob参数配置
     */
    private Map<String, ElasticJobConfigurationProperties> setJobParameters(Properties jobProperties, ElasticJobProperties elasticJobProperties) {
        Map<String, ElasticJobConfigurationProperties> jobs = elasticJobProperties.getJobs();
        // 遍历刷新job动态参数配置
        for (Map.Entry<String, ElasticJobConfigurationProperties> entry : jobs.entrySet()) {
            ElasticJobConfigurationProperties properties = entry.getValue();
            properties.setCron((String) jobProperties.get(entry.getKey() + ".cron"));
            properties.setShardingTotalCount(Integer.parseInt((String) jobProperties.get(entry.getKey() + ".shardingTotalCount")));
            properties.setShardingItemParameters((String) jobProperties.get(entry.getKey() + ".shardingItemParameters"));
        }
        return jobs;
    }

    @Override
    public void reload() throws IOException {
        log.info("============job配置发生变化=============");
        Properties jobProperties = propertiesFactoryBean.getObject();
        this.setJobParameters(jobProperties, elasticJobProperties);
    }
}
